package tabs;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
import javax.swing.table.TableModel;

import widgets.TableGrid;
import widgets.TableGridElement;
import classes.Content;
import classes.Page;
import classes.SimpleImage;
import classes.SimpleText;

/**
 * Classe da aba de configuração dos elementos do objeto.
 * 
 * @author Renato Nunes
 */
@SuppressWarnings("serial")
public class ElementsTab extends JPanel
{    
    /**
     *	Tabela de conteúdos da página. 
     */
    private TableGrid tableModel; 
    
    /**
     * Painéis de edição de texto e de edição de imagem.
     */
 	private JLabel labelImageProp = new JLabel( "Propriedades da imagem:" );
 	private JPanel panelImageProp = new JPanel();
 	private JLabel labelTextProp = new JLabel( "Propriedades do texto:" );
 	private JPanel panelTextProp = new JPanel();

    /**
     * Campos de edição de texto.
     */
 	private JTextArea inputTextField;
 	private JTextField sizeTextField;
 	//private JComboBox fontTextField;

    /**
     * Campos de edição de imagens.
     */
 	private JTextField fileImageField;
 	private JTextField legendImageField;
 	//private JTextField widthImageField;
 	//private JTextField heightImageField;
    
    /**
     * Página corrente que está sendo editada.
     */
 	private Page currentPage = new Page();

    /**
     * Identificador do conteúdo corrente (que está sendo editado).
     */
 	private String idOfCurrentContent = "";

    /**
     * Grid de elementos de uma página.
     */
 	private JTable gridElementos;

    /**
     * Botões de manipulação de elementos das páginas.
     */
 	private JButton btnAddText = new JButton( "Adicionar Texto" );
 	private JButton btnAddImage = new JButton( "Adicionar Imagem" );
    private JButton btnRemoveElement   = new JButton( "Excluir Elemento" );
	    
	public ElementsTab()
	{
		setLayout( null );

		setupTable();
		setupTextFields();
		setupImageFields();
		
		// Por default não mostra nenhum dos dois painéis.
		hidePropPanels();
	}
	
	/**
	 * Configura a tabela de elementos de uma página. 
	 */
	public void setupTable()
	{
		JLabel lblElementos = new JLabel( "Elementos: " );
		lblElementos.setBounds( 10, 40, 100, 20 );
		add( lblElementos );
		
		JPanel panel_Elementos = new JPanel();
		panel_Elementos.setLayout( null );
		panel_Elementos.setBorder( new LineBorder( new Color( 0, 0, 0 ) ) );
		panel_Elementos.setBounds( 10, 70, 390, 310 );
		add( panel_Elementos );

		// Configura botão para adicionar texto.
		btnAddText.setBounds( 10, 10, 150, 20 );
		btnAddText.addMouseListener( new MouseAdapter() {
			public void mouseClicked(MouseEvent e)
			{
				addTextClicked();
			}
		});
		panel_Elementos.add( btnAddText );
		
		// Configura botão para adicionar imagens.
		btnAddImage.setBounds( 170, 10, 150, 20 );
		btnAddImage.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent e)
			{
				addImageClicked();
			}
		});
		panel_Elementos.add( btnAddImage );
		
		JScrollPane scrollPaneElementos = new JScrollPane( getTableElementos() );
		scrollPaneElementos.setBounds( 10, 40, 370, 230 );
		panel_Elementos.add( scrollPaneElementos );
		
		// Configura botão para remover elemento.
		btnRemoveElement.addActionListener( new ActionListener() {
			public void actionPerformed( ActionEvent e ) 
			{
				removeElementClicked();
			}
		});
		btnRemoveElement.setBounds( 230, 280, 150, 20 );
		panel_Elementos.add( btnRemoveElement );
	}
	
	/**
	 * Configura o painel de edição de algum texto da página. 
	 */
	public void setupTextFields()
	{
		labelTextProp.setBounds( 410, 40, 180, 20 );
		add( labelTextProp );
		
		panelTextProp.setBorder( new LineBorder( new Color( 0, 0, 0 ) ) );
		panelTextProp.setBounds( 410, 70, 280, 310 );
		panelTextProp.setLayout( null );
		add(panelTextProp);
		
		inputTextField = new JTextArea();
		inputTextField.setBounds( 10, 20, 260, 150 );
		inputTextField.setColumns( 10 );
		inputTextField.setLineWrap( true );

		JScrollPane sbrText;
		sbrText = new JScrollPane( inputTextField );
		sbrText.setBounds( 10, 20, 260, 150 );
		sbrText.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );
		panelTextProp.add(sbrText);
		
		/*JLabel lblNewLabel_3 = new JLabel( "Fonte: " );
		lblNewLabel_3.setBounds( 10, 190, 70, 20 );
		panelTextProp.add( lblNewLabel_3 );*/
		
		JLabel lblNewLabel_4 = new JLabel( "Tamanho: " );
		lblNewLabel_4.setBounds( 10, 190, 70, 20 );
		panelTextProp.add( lblNewLabel_4 );
		
		sizeTextField = new JTextField();
		sizeTextField.setText( "12" );
		sizeTextField.setBounds( 90, 190, 180, 20 );
		sizeTextField.setColumns( 10 );
		panelTextProp.add( sizeTextField );
		
		/*fontTextField = new JComboBox();
		fontTextField.setModel(new DefaultComboBoxModel(new String[] {"Arial", "Times New Roman", "Courrier New"}));
		fontTextField.setBounds(90, 230, 180, 20);
		panelTextProp.add(fontTextField);*/
		
		JButton okBtn = new JButton( "OK" );
		okBtn.setBounds( 110, 270, 60, 20 );
		okBtn.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent arg0) 
			{
				saveTextClicked();
			}
		});
		panelTextProp.add( okBtn );
		
		setAvaliableTextFields( false );
	}
	
	/**
	 *	Configura o painel de edição de alguma imagem da página. 
	 */
	public void setupImageFields()
	{
		labelImageProp.setBounds( 410, 40, 180, 20 );
		add( labelImageProp );

		panelImageProp.setLayout( null );
		panelImageProp.setBorder( new LineBorder( new Color( 0, 0, 0 ) ) );
		panelImageProp.setBounds( 410, 70, 280, 310 );
		add( panelImageProp );

		JLabel lblNewLabel_5 = new JLabel( "Arquivo: " );
		lblNewLabel_5.setBounds( 10, 20, 70, 20 );
		panelImageProp.add( lblNewLabel_5 );
		
		JLabel lblAltura_2 = new JLabel( "Legenda:" );
		lblAltura_2.setBounds( 10, 60, 70, 20 );
		panelImageProp.add( lblAltura_2 );
		
		/*JLabel lblLargura = new JLabel("Largura:");
		lblLargura.setBounds(10, 100, 70, 20);
		panelImageProp.add(lblLargura);
		
		JLabel lblAltura_1 = new JLabel("Altura: ");
		lblAltura_1.setBounds(10, 140, 70, 20);
		panelImageProp.add(lblAltura_1);*/
		
		fileImageField = new JTextField();
		fileImageField.setBounds( 90, 20, 180, 20 );
		fileImageField.setColumns( 10 );
		panelImageProp.add( fileImageField );
		
		legendImageField = new JTextField();
		legendImageField.setBounds( 90, 60, 180, 20 );
		legendImageField.setColumns (10 );
		panelImageProp.add( legendImageField );
		
		/*widthImageField = new JTextField();
		widthImageField.setBounds(90, 100, 180, 20);
		widthImageField.setColumns(10);
		panelImageProp.add(widthImageField);
		
		heightImageField = new JTextField();
		heightImageField.setBounds(90, 149, 180, 20);
		heightImageField.setColumns(10);
		panelImageProp.add(heightImageField); */
		
		JButton okBtn = new JButton( "OK" );
		okBtn.setBounds( 110, 270, 60, 20 );
		okBtn.addActionListener( new ActionListener() {
			public void actionPerformed(ActionEvent arg0) 
			{
				saveImageClicked();
			}
		});
		panelImageProp.add( okBtn );
		
		setAvaliableImageFields( false );
	}
	
	/**
	 *	Trata do evento de clique no botão para adicionar texto na página. 
	 */
	private void addTextClicked()
	{
		int id = currentPage.getMaxIdOfContent() + 1;
		
		// Adiciona texto na p�gina.
		SimpleText st = new SimpleText();
		st.setId( String.valueOf( id ) );
		st.setSize( "12" );
		st.setText( "Novo Texto" );
		currentPage.getContents().add( st );
		
		// Adiciona texto no grid.
		tableModel.addElemento( new TableGridElement( st.getId(), st.getText() ,"Texto" ) );
		gridElementos.setRowSelectionInterval( tableModel.getRowCount() -1, tableModel.getRowCount() -1 );
		
		// Mostra o painel de configuração de texto.
		setAvaliableImageFields(false);
		setAvaliableTextFields(true);
		showTextProp();
	}
	
	/**
	 *	Trata do evento de clique no botão para adicionar imagem na página. 
	 */
	private void addImageClicked()
	{
		int id = currentPage.getMaxIdOfContent() + 1;
		
		// Adiciona imagem na página.
		SimpleImage si = new SimpleImage();
		si.setId( String.valueOf( id ) );
		si.setLegend( "Nova Imagem" );
		si.setHeight( "320" );
		si.setWidth( "480");
		currentPage.getContents().add( si );
		
		// Adiciona imagem no grid.
		tableModel.addElemento( new TableGridElement( si.getId(), si.getLegend(), "Imagem" ) );
		gridElementos.setRowSelectionInterval( tableModel.getRowCount() -1, tableModel.getRowCount() -1 );
		
		// Mostra o painel de configurações de imagens.
		setAvaliableImageFields( true );
		setAvaliableTextFields( false );
		showImageProp();
	}
	
	/**
	 *	Trata do evento de clique no botão para remover elemento na página. 
	 */
	private void removeElementClicked()
	{
		// Verifica se existe uma linha selecionada.
		if( gridElementos.getSelectedRow() != -1 )
		{
			String id = tableModel.getElemento( gridElementos.getSelectedRow() ).getId();
			Content c = currentPage.getContentById( id ); 
			
			// Remove o elemento da página.
			currentPage.getContents().remove( c );
			
			// Remove o elemnto do grid.
			tableModel.removeElemento( gridElementos.getSelectedRows() );
		}

		// Esconde os painéis.
		hidePropPanels();
	}
	
	
	/**
	 * Salva as informações modificadas do texto. 
	 */
	private void saveTextClicked()
	{
		Content c = currentPage.getContentById( idOfCurrentContent );
		SimpleText st = (SimpleText)c;
		st.setText( inputTextField.getText() );
		st.setSize( sizeTextField.getText() );
		
		// Atualiza grid.
		int selectedRow = gridElementos.getSelectedRow();
		TableGridElement el = tableModel.getElemento( selectedRow );
		el.setNome( inputTextField.getText() );
		tableModel.fireTableDataChanged();
		gridElementos.setRowSelectionInterval( selectedRow, selectedRow );
	}
	
	/**
	 * Salva as informações modificadas da imagem. 
	 */
	private void saveImageClicked()
	{
		Content c = currentPage.getContentById( idOfCurrentContent );
		SimpleImage si = (SimpleImage)c;
		si.setPath( fileImageField.getText() );
		si.setLegend( legendImageField.getText() );
		
		// Atualiza grid.
		int selectedRow = gridElementos.getSelectedRow();
		TableGridElement el = tableModel.getElemento( selectedRow );
		el.setNome( legendImageField.getText() );
		tableModel.fireTableDataChanged();
		gridElementos.setRowSelectionInterval( selectedRow, selectedRow );
	}
	
	/**
	 *	Carrega os elementos de uma página. 
	 */
	public void loadElementsOfPage( Page page )
	{
		currentPage = page;
		tableModel.clear();
		
		// Adiciona o conte�do da p�gina ao grid.
		for( Content c : currentPage.getContents() )
		{
			if( c instanceof SimpleText )
			{
				SimpleText st = (SimpleText) c;
				String id = st.getId();
				String info = st.getText();
				tableModel.addElemento(new TableGridElement( id, info, "Texto"));
			}
			else if( c instanceof SimpleImage )
			{
				SimpleImage si = (SimpleImage) c;
				String id = si.getId();
				String info = si.getLegend();
				tableModel.addElemento(new TableGridElement( id, info, "Imagem"));
			}
		}
		
		hidePropPanels();
	}
	
	/**
	 * Limpa todas as informações da tela. 
	 */
	public void clearProp()
	{
		clearTextProp();
		clearImageProp();
		hidePropPanels();
		
		tableModel.clear();
	}

	/**
	 * Limpa as propriedades de um texto.
	 */
	public void clearTextProp()
	{
		sizeTextField.setText( "" );
		inputTextField.setText( "" );
	}
	
	/**
	 *	Limpa as propriedades de uma imagem. 
	 */
	public void clearImageProp()
	{
		fileImageField.setText( "" );
		legendImageField.setText( "" );
		//widthImageField.setText( "" );
		//heightImageField.setText( "" );
	}
	
	
	public void setAvaliableTextFields( boolean avaiable ) 
	{
		sizeTextField.setEnabled(avaiable);
		inputTextField.setEnabled(avaiable);
		//fontTextField.setEnabled(avaiable);
	}
	
	public void setAvaliableImageFields( boolean avaiable ) 
	{
		fileImageField.setEnabled(avaiable);
		legendImageField.setEnabled(avaiable);
		//heightImageField.setEnabled(avaiable);
		//widthImageField.setEnabled(avaiable);	
	}

   /**
    * Mostra o painel de edição de um texto e esconde o painel de edição de uma
    * imagem.
    */
	public void showTextProp()
	{
		panelTextProp.setVisible( true );
		labelTextProp.setVisible( true );
		
		panelImageProp.setVisible( false );
		labelImageProp.setVisible( false );
	
		fileImageField.setText( "" );
		legendImageField.setText( "" );
		//widthImageField.setText( "" );
		//heightImageField.setText( "" );
	}

   /**
    * Mostra o painel de edição de uma imagem e esconde o painel de edição de um
    * texto.
    */
	public void showImageProp()
	{
		panelTextProp.setVisible( false );
		labelTextProp.setVisible( false );
		
		panelImageProp.setVisible( true );
		labelImageProp.setVisible( true );
		
		inputTextField.setText( "" );
		sizeTextField.setText( "" );
	}
	
	public void hidePropPanels()
	{
		panelTextProp.setVisible( false );
		labelTextProp.setVisible( false );
		
		panelImageProp.setVisible( false );
		labelImageProp.setVisible( false );
	}
	
	/**
	 *	Preenche os campos de um texto selecionado. 
	 */
	public void fillTextProp()
	{
		Content c = currentPage.getContentById( idOfCurrentContent );
		SimpleText st = (SimpleText) c;
		inputTextField.setText( st.getText() );
		sizeTextField.setText( st.getSize() );
	}
	
	/**
	 *	Preenche os campos de uma imagem selecionada. 
	 */
	public void fillImageProp()
	{
		Content c = currentPage.getContentById( idOfCurrentContent );
		SimpleImage si = (SimpleImage) c;
		fileImageField.setText( si.getPath() );
		legendImageField.setText( si.getLegend() );
		//widthImageField.setText( si.getWidth() );
		//heightImageField.setText( si.getHeight() );
	}
	
	private JTable getTableElementos() 
	{
        if ( gridElementos == null ) 
        {
            gridElementos = new JTable();
            gridElementos.setModel( getTableModel() );
            gridElementos.setSelectionMode( 0 );
            
            gridElementos.addMouseListener( new MouseAdapter() {
    			public void mouseClicked(MouseEvent e)
    			{
    				if( tableModel.getElemento( gridElementos.getSelectedRow() ).getTipo() == "Texto" ) 
    				{
    					setAvaliableTextFields( true );
    					setAvaliableImageFields( false );

    					// Mostra as propriedades de texto.
    					showTextProp();
    					
    					// Preenche com os valores devidos.
    					idOfCurrentContent = tableModel.getElemento( gridElementos.getSelectedRow() ).getId();
    					fillTextProp();
    				}
    				else if( tableModel.getElemento( gridElementos.getSelectedRow() ).getTipo() == "Imagem" ) 
    				{
    					setAvaliableTextFields( false );
    					setAvaliableImageFields( true );

    					// Mostra as propriedades de imagem.
    					showImageProp();
    					
    					// Preenche com os valores devidos.
    					idOfCurrentContent = tableModel.getElemento( gridElementos.getSelectedRow() ).getId();
    					fillImageProp();
    				}
    				else 
    				{
    					setAvaliableTextFields( false );
    					setAvaliableImageFields( false );
    				}	
    			}
    		});
        }
        
        // Seta o tamanho das colunas.
        gridElementos.getColumnModel().getColumn(0).setPreferredWidth( 40 );
        gridElementos.getColumnModel().getColumn(1).setPreferredWidth( 270 );
        gridElementos.getColumnModel().getColumn(2).setPreferredWidth( 60 );
        
        return gridElementos;
    } 

	
	private TableModel getTableModel() 
	{
		if (tableModel == null) 
            tableModel = new TableGrid();  
        return tableModel;  
	}
}
